package com.dongdong.bookstore.module.pms.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dongdong.bookstore.common.exception.Asserts;
import com.dongdong.bookstore.module.pms.dto.BookCategoryDto;
import com.dongdong.bookstore.module.pms.dto.BookCategroyNode;
import com.dongdong.bookstore.module.pms.model.BookCategory;
import com.dongdong.bookstore.module.pms.mapper.BookCategoryMapper;
import com.dongdong.bookstore.module.pms.model.CategorySubjectRelation;
import com.dongdong.bookstore.module.pms.service.BookCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dongdong.bookstore.module.pms.service.CategorySubjectRelationService;
import com.dongdong.bookstore.module.ums.model.Menu;
import com.dongdong.bookstore.module.ums.viewmodel.MenuNode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 书籍分类表 服务实现类
 * </p>
 *
 * @author chiangkai
 * @since 2021-10-31
 */
@Service
public class BookCategoryServiceImpl extends ServiceImpl<BookCategoryMapper, BookCategory> implements BookCategoryService {

    @Autowired
    private CategorySubjectRelationService categorySubjectRelationService;

    @Override
    @CacheEvict(value = "cateTree")
    public boolean create(BookCategoryDto dto) {
        BookCategory bookCategory = new BookCategory();
        BeanUtils.copyProperties(dto, bookCategory);
        Long parentId = dto.getParentId();
        if (parentId.equals(0)) {
            bookCategory.setParentId(0L);
            bookCategory.setLevel(0);
        } else {
            updateCategoryLevel(bookCategory);
        }
        save(bookCategory);
        Long categoryId = bookCategory.getId();
        if (CollUtil.isNotEmpty(dto.getSubjectIds())) {
            List<Long> subjectIds = dto.getSubjectIds();
            ArrayList<CategorySubjectRelation> relations = generousCateSubjectRelationBySubjectIdsAndCategoryId(categoryId, subjectIds);
            categorySubjectRelationService.saveBatch(relations);
        }
        return true;
    }

    private ArrayList<CategorySubjectRelation> generousCateSubjectRelationBySubjectIdsAndCategoryId(Long categoryId, List<Long> subjectIds) {
        ArrayList<CategorySubjectRelation> categorySubjectRelations = new ArrayList<>();
        subjectIds.forEach(subjectId -> {
            CategorySubjectRelation categorySubjectRelation = new CategorySubjectRelation();
            categorySubjectRelation.setCategoryId(categoryId);
            categorySubjectRelation.setSubjectId(subjectId);
            categorySubjectRelations.add(categorySubjectRelation);
        });
        return categorySubjectRelations;
    }

    @Override
    @CacheEvict(value = "cateTree")
    public boolean update(Long id, BookCategoryDto dto) {
        BookCategory target = getById(id);
        Asserts.isNull(target, "更新的分类不存在");
        BeanUtils.copyProperties(dto, target);
        updateCategoryLevel(target);
        QueryWrapper<CategorySubjectRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CategorySubjectRelation::getCategoryId, target.getId());
        categorySubjectRelationService.remove(wrapper);
        if (CollUtil.isNotEmpty(dto.getSubjectIds())) {
            List<Long> subjectIds = dto.getSubjectIds();
            ArrayList<CategorySubjectRelation> relations = generousCateSubjectRelationBySubjectIdsAndCategoryId(target.getId(), subjectIds);
            categorySubjectRelationService.saveBatch(relations);
        }
        return updateById(target);
    }

    @Override
    @Cacheable(value = "cateTree")
    public List<BookCategroyNode> listTree() {
        List<BookCategroyNode> result = null;
        List<BookCategory> list = list();
        if (!CollUtil.isEmpty(list)) {
            result = list.stream().filter(category -> category.getParentId().equals(0L))
                    .map(topCategory -> covertCateNode(topCategory, list)).collect(Collectors.toList());
        }
        return result;
    }

    private BookCategroyNode covertCateNode(BookCategory topCategory, List<BookCategory> list) {
        BookCategroyNode bookCategroyNode = new BookCategroyNode();
        BeanUtils.copyProperties(topCategory, bookCategroyNode);
        List<BookCategroyNode> collect = list.stream().filter(submenu -> submenu.getParentId().equals(topCategory.getId())).map(submenu -> covertCateNode(submenu, list)).collect(Collectors.toList());
        bookCategroyNode.setChildren(collect);
        return bookCategroyNode;
    }

    private void updateCategoryLevel(BookCategory bookCategory) {
        BookCategory parent = getById(bookCategory.getParentId());
        Asserts.isNull(parent, "父菜单不存在");
        bookCategory.setLevel(parent.getLevel() + 1);
    }
}
